import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Patch, Post, Query } from '@nestjs/common'
import { ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger'
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator'
import { definePermission, Perm } from '~/modules/admin/auth/decorators/permission.decorator'

import { CreateStudentDto } from './dto/create-student.dto'
import { CreateStudentClassDto } from './dto/create-student-class.dto'
import { QueryStudentDto } from './dto/query-student.dto'
import { UpdateStudentDto } from './dto/update-student.dto'
import { UpdateStudentClassDto } from './dto/update-student-class.dto'
import { UpdateStudentExpireDto } from './dto/update-student-expire.dto'
import { UpdateStudentPasswordDto } from './dto/update-student-password.dto'
import { StudentService } from './student.service'
import { OverallAttendanceStatisticsDto } from './dto/overall-attendance-statistics.dto'
import { StudentWithClassInfoDto } from './dto/student-with-class-info.dto'
import { StudentDetailDto } from './dto/student-detail.dto'
import { StudentCheckinStatisticsDto } from './dto/student-checkin-statistics.dto'

export const permissions = definePermission('manage:student', {
  LIST: 'list',
  CREATE: 'create',
  READ: 'read',
  UPDATE: 'update',
  DELETE: 'delete',
  UPDATE_EXPIRE: 'expire',
  UPDATE_PASSWORD: 'password',
  CLASS: 'class',
  ATTENDANCE_STATISTICS: 'attendance_statistics',
  STUDENT_WITH_CLASS: 'student_with_class',
  DETAIL: 'detail',
  CHECKIN_STATISTICS: 'checkin_statistics',
} as const)

@ApiTags('Manage - 学生管理')
@ApiSecurityAuth()
@Controller('admin/manage/student')
export class StudentController {
  constructor(private readonly studentService: StudentService) {}

  @ApiOperation({ summary: '创建学生' })
  @ApiResponse({ status: 201, description: '创建成功' })
  @HttpCode(HttpStatus.CREATED)
  @Perm(permissions.CREATE)
  @Post()
  create(@Body() createStudentDto: CreateStudentDto) {
    return this.studentService.create(createStudentDto)
  }

  @ApiOperation({ summary: '获取学生列表（分页）' })
  @ApiResponse({ status: 200, description: '获取成功' })
  @Perm(permissions.LIST)
  @Get()
  findAll(@Query() query: QueryStudentDto) {
    return this.studentService.findAll(query)
  }

  @ApiOperation({ summary: '获取单个学生' })
  @ApiParam({ name: 'id', description: '学生ID' })
  @ApiResponse({ 
    status: 200, 
    description: '获取成功',
    schema: {
      type: 'object',
      properties: {
        id: { type: 'number', example: 1 },
        studentId: { type: 'string', example: 'STU202400001' },
        phone: { type: 'string', example: '13800138000' },
        userName: { type: 'string', example: '张三' },
        userId: { type: 'number', example: 101 },
        studentType: { type: 'number', example: 1, description: '学生类型(1-线上/2-线下)' },
        startAt: { type: 'string', format: 'date-time' },
        expireAt: { type: 'string', format: 'date-time' },
        status: { type: 'number', example: 1, description: '学生状态(0-停用/1-学习中/2-待续费/4-已毕业)' },
        createdAt: { type: 'string', format: 'date-time' },
        updatedAt: { type: 'string', format: 'date-time' },
        userRealName: { type: 'string', example: '张三' },
        userPhone: { type: 'string', example: '13800138000' },
        guarder: { type: 'string', example: '张父' },
        guarderPhone: { type: 'string', example: '13900139000' },
        guarderRelation: { type: 'string', example: '父亲' },
        birthday: { type: 'string', format: 'date' },
        grade: { type: 'string', example: '三年级' },
        school: { type: 'string', example: '实验小学' },
        totalCheckinDays: { type: 'number', example: 15, description: '总打卡天数' },
        totalCheckinRate: { type: 'string', example: '75%', description: '总体打卡率' },
        classes: { 
          type: 'array', 
          description: '班级列表', 
          items: {
            type: 'object',
            properties: {
              classId: { type: 'string', example: 'CLASS001' },
              className: { type: 'string', example: '英语基础班' },
              classGrade: { type: 'number', example: 3, description: '班级学级' },
              teacherName: { type: 'string', example: '李老师' },
              teacherId: { type: 'number', example: 201 },
              startAt: { type: 'string', format: 'date-time' },
              expireAt: { type: 'string', format: 'date-time' },
              status: { type: 'number', example: 1 },
              studyPlan: { 
                type: 'array', 
                description: '学习计划',
                items: { type: 'string' },
                example: ['英语单词', '语法', '阅读', '听力'] 
              },
              checkinDays: { type: 'number', example: 10, description: '该班级打卡天数' },
              lastCheckinAt: { type: 'string', format: 'date-time', description: '最后打卡时间' },
              joinAt: { type: 'string', format: 'date-time', description: '加入班级时间' },
              checkinRate: { type: 'string', example: '80%', description: '该班级打卡率' }
            }
          } 
        }
      }
    }
  })
  @Perm(permissions.READ)
  @Get(':id')
  findOne(@Param('id', ParseIntPipe) id: number) {
    return this.studentService.findOne(+id)
  }

  @ApiOperation({ summary: '更新学生信息' })
  @ApiParam({ name: 'id', description: '学生ID' })
  @ApiResponse({ status: 200, description: '更新成功' })
  @Perm(permissions.UPDATE)
  @Patch(':id')
  update(@Param('id', ParseIntPipe) id: number, @Body() updateStudentDto: UpdateStudentDto) {
    return this.studentService.update(+id, updateStudentDto)
  }

  @ApiOperation({ summary: '调整学生有效期' })
  @ApiParam({ name: 'id', description: '学生ID' })
  @ApiResponse({ status: 200, description: '调整成功' })
  @Perm(permissions.UPDATE_EXPIRE)
  @Patch(':id/expire')
  updateExpire(@Param('id', ParseIntPipe) id: number, @Body() updateExpireDto: UpdateStudentExpireDto) {
    return this.studentService.updateExpire(+id, updateExpireDto)
  }

  @ApiOperation({ summary: '修改学生密码' })
  @ApiParam({ name: 'id', description: '学生ID' })
  @ApiResponse({ status: 200, description: '修改成功' })
  @Perm(permissions.UPDATE_PASSWORD)
  @Patch(':id/password')
  updatePassword(@Param('id', ParseIntPipe) id: number, @Body() updatePasswordDto: UpdateStudentPasswordDto) {
    return this.studentService.updatePassword(+id, updatePasswordDto)
  }

  @ApiOperation({ summary: '删除学生' })
  @ApiParam({ name: 'id', description: '学生ID' })
  @ApiResponse({ status: 200, description: '删除成功' })
  @HttpCode(HttpStatus.NO_CONTENT)
  @Perm(permissions.DELETE)
  @Delete(':id')
  remove(@Param('id', ParseIntPipe) id: number) {
    return this.studentService.remove(+id)
  }

  @ApiOperation({ summary: '获取新的学生ID' })
  @ApiResponse({ status: 200, description: '获取成功' })
  @Get('new/student-id')
  getNewStudentId() {
    return this.studentService.getNewStudentId()
  }

  @ApiOperation({ summary: '添加学生到班级' })
  @ApiResponse({ status: 201, description: '添加成功' })
  @HttpCode(HttpStatus.CREATED)
  @Perm(permissions.CLASS)
  @Post('class')
  addStudentToClass(@Body() createStudentClassDto: CreateStudentClassDto) {
    return this.studentService.addStudentToClass(createStudentClassDto)
  }

  @ApiOperation({ summary: '更新学生班级信息' })
  @ApiParam({ name: 'id', description: '学生班级关联ID' })
  @ApiResponse({ status: 200, description: '更新成功' })
  @Perm(permissions.CLASS)
  @Patch('class/:id')
  updateStudentClass(@Param('id', ParseIntPipe) id: number, @Body() updateStudentClassDto: UpdateStudentClassDto) {
    return this.studentService.updateStudentClass(+id, updateStudentClassDto)
  }

  @ApiOperation({ summary: '获取学生班级列表', description: '获取学生加入的所有班级列表' })
  @ApiParam({ name: 'studentId', description: '学生ID' })
  @ApiResponse({ status: 200, description: '学生班级列表' })
  @Perm(permissions.CLASS)
  @Get(':studentId/classes')
  findStudentClasses(@Param('studentId', ParseIntPipe) studentId: number) {
    return this.studentService.findStudentClasses(+studentId)
  }

  @ApiOperation({ summary: '获取所有已分配班级学生的打卡统计', description: '获取所有已分配班级学生的打卡统计数据，包括总体、季度、月度和周度数据' })
  @ApiResponse({ 
    status: 200, 
    description: '获取成功',
    type: OverallAttendanceStatisticsDto
  })
  @Perm(permissions.ATTENDANCE_STATISTICS)
  @Get('statistics/attendance')
  getOverallAttendanceStatistics() {
    return this.studentService.getOverallAttendanceStatistics();
  }

  @ApiOperation({ summary: '获取所有已分配班级的学生信息', description: '获取包含班级信息、打卡统计等数据的学生列表' })
  @ApiResponse({ 
    status: 200, 
    description: '获取成功',
    type: [StudentWithClassInfoDto]
  })
  @Perm(permissions.STUDENT_WITH_CLASS)
  @Get('with-class-info')
  getStudentsWithClassInfo() {
    return this.studentService.getStudentsWithClassInfo();
  }

  @ApiOperation({ summary: '获取学生详情信息', description: '获取学生的详细信息，包含个人信息、班级信息等' })
  @ApiParam({ name: 'id', description: '学生ID', required: true, type: Number })
  @ApiResponse({ 
    status: 200, 
    description: '学生详情',
    type: StudentDetailDto
  })
  @Perm(permissions.DETAIL)
  @Get(':id/detail')
  getStudentDetail(@Param('id', ParseIntPipe) id: number) {
    return this.studentService.getStudentDetail(id);
  }

  @ApiOperation({ summary: '获取学生打卡统计数据', description: '获取指定学生的总体、季度、月度和周度打卡统计数据' })
  @ApiParam({ name: 'id', description: '学生ID', required: true, type: Number })
  @ApiResponse({ 
    status: 200, 
    description: '获取成功',
    type: StudentCheckinStatisticsDto
  })
  @Perm(permissions.CHECKIN_STATISTICS)
  @Get(':id/checkin-statistics')
  getStudentCheckinStatistics(@Param('id', ParseIntPipe) id: number) {
    return this.studentService.getStudentCheckinStatistics(id);
  }
}
